﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace KingOfCSharp.iHunter.Plugins.BayesianFilter
{
    /// <summary>
    /// A list of words along with counts of how often those words appear.
    /// </summary>
    public class Corpus
    {
        /// <summary>
        /// Pattern for words that don't start with a number, but can be anything after
        /// </summary>
        public const string TokenPattern = @"([a-zA-Z]\w+)\W*";

        private SortedDictionary<string, int> _tokens = new SortedDictionary<string, int>();

        /// <summary>
        /// A sorted list of all the words that show up in the text, along with counts of how many times they appear.
        /// </summary>
        public SortedDictionary<string, int> Tokens
        {
            get { return _tokens; }
        }

        public Corpus()
        {
        }

        public Corpus(TextReader reader)
        {
            LoadFromReader(reader);
        }

        public Corpus(string filepath)
        {
            LoadFromReader(new StreamReader(filepath));
        }

        /// <summary>
        /// Loads tokens from the specified TextReader into the Corpus.
        /// </summary>
        /// <param name="reader"></param>
        public void LoadFromReader(TextReader reader)
        {
            Regex re = new Regex(TokenPattern, RegexOptions.Compiled);
            string line = "";
            while ((line = reader.ReadLine()) != null)
            {
                Match m = re.Match(line);
                while (m.Success)
                {
                    AddToken(m.Groups[1].Value);
                    m = m.NextMatch();
                }
            }
        }

        /// <summary>
        /// Save a word, if it's already there, add its count.
        /// </summary>
        /// <param name="word"></param>
        public void AddToken(string word)
        {
            if (!_tokens.ContainsKey(word))
            {
                _tokens.Add(word, 1);
            }
            else
            {
                _tokens[word]++;
            }
        }
    }
}
